package main

import (
	"bufio"
	"crypto/rand"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"io"
	"math/big"
	"os"
	"path/filepath"
	"strings"
	"time"
)

// 生成随机字符串的函数
func generateRandomID(length int, formatType string) string {
	if formatType == "uuid" {
		// 生成类似 UUID 的随机字符串（8-4-4-4-12）
		parts := []string{
			generateRandomHex(8),
			generateRandomHex(4),
			generateRandomHex(4),
			generateRandomHex(4),
			generateRandomHex(12),
		}
		return strings.Join(parts, "-")
	} else if formatType == "hex" {
		// 生成类似十六进制的随机字符串
		return generateRandomHex(length)
	} else {
		// 生成包含数字、英文大小写的随机字符串
		const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
		result := make([]byte, length)
		for i := 0; i < length; i++ {
			num, _ := rand.Int(rand.Reader, big.NewInt(int64(len(chars))))
			result[i] = chars[num.Int64()]
		}
		return string(result)
	}
}

// 生成随机十六进制字符串
func generateRandomHex(length int) string {
	bytes := make([]byte, length/2+1)
	rand.Read(bytes)
	return hex.EncodeToString(bytes)[:length]
}

// 修改设备 ID 的函数
func modifyDeviceIDs(filePath string) error {
	// 读取 JSON 文件
	fileData, err := os.ReadFile(filePath)
	if err != nil {
		return fmt.Errorf("读取文件错误: %v", err)
	}

	// 解析 JSON 数据
	var data map[string]interface{}
	if err := json.Unmarshal(fileData, &data); err != nil {
		return fmt.Errorf("解析 JSON 错误: %v", err)
	}

	// 修改设备 ID
	if _, ok := data["telemetry.sqmId"]; ok {
		data["telemetry.sqmId"] = "{" + generateRandomID(36, "uuid") + "}" // 类似 {E3DB74FD-D35A-430D-9D0C-0AFF91442298}
	}
	if _, ok := data["telemetry.macMachineId"]; ok {
		data["telemetry.macMachineId"] = generateRandomID(36, "uuid") // 类似 9b8e269d-bbe7-4095-bdb2-8b09be49bfdb
	}
	if _, ok := data["telemetry.machineId"]; ok {
		data["telemetry.machineId"] = generateRandomID(64, "hex") // 类似 d7769fd3f9534d4c8112490c21402c87a1a11e90466146a997e5468db7809741
	}
	if _, ok := data["telemetry.devDeviceId"]; ok {
		data["telemetry.devDeviceId"] = generateRandomID(36, "uuid") // 类似 a965ba4a-f591-4634-8187-1ad2d94c1928
	}

	// 将修改后的数据写回文件
	modifiedData, err := json.MarshalIndent(data, "", "    ")
	if err != nil {
		return fmt.Errorf("JSON 格式化错误: %v", err)
	}

	if err := os.WriteFile(filePath, modifiedData, 0644); err != nil {
		return fmt.Errorf("写入文件错误: %v", err)
	}

	// 打印修改后的设备 ID
	fmt.Println("更改后的设备 ID 内容：")
	if val, ok := data["telemetry.sqmId"]; ok {
		fmt.Printf("telemetry.sqmId: %v\n", val)
	}
	if val, ok := data["telemetry.macMachineId"]; ok {
		fmt.Printf("telemetry.macMachineId: %v\n", val)
	}
	if val, ok := data["telemetry.machineId"]; ok {
		fmt.Printf("telemetry.machineId: %v\n", val)
	}
	if val, ok := data["telemetry.devDeviceId"]; ok {
		fmt.Printf("telemetry.devDeviceId: %v\n", val)
	}

	fmt.Println("设备 ID 已成功修改！")
	return nil
}

// 创建备份文件的函数
func createBackupFile(backupDir string) error {
	// 生成文件名（例如：MachineGuid_20250205_115616.txt）
	timestamp := time.Now().Format("20060102_150405")
	fileName := fmt.Sprintf("MachineGuid_%s.txt", timestamp)
	filePath := filepath.Join(backupDir, fileName)

	// 生成随机内容（类似 05d2138d-3388-4911-aa48-5e3c5add0077）
	content := generateRandomID(36, "uuid")

	// 写入文件
	if err := os.WriteFile(filePath, []byte(content), 0644); err != nil {
		return fmt.Errorf("创建备份文件错误: %v", err)
	}

	fmt.Printf("备份文件已创建：%s\n", filePath)
	fmt.Printf("文件内容：%s\n", content)
	return nil
}

func main() {
	// 用户输入
	reader := bufio.NewReader(os.Stdin)
	fmt.Print("请选择模式（输入 1: Win 模式, 2: macOS 模式, 3: Linux 模式）: ")
	input, _ := reader.ReadString('\n')
	input = strings.TrimSpace(input)

	var filePath string
	var backupDir string

	switch input {
	case "1":
		// Win 模式
		fmt.Println("Win 修改 ID 模式")
		appdataDir := os.Getenv("APPDATA")
		if appdataDir == "" {
			fmt.Println("无法获取 %APPDATA% 目录路径！")
			os.Exit(1)
		}
		filePath = filepath.Join(appdataDir, "Cursor", "User", "globalStorage", "storage.json")
		backupDir = filepath.Join(appdataDir, "MachineGuid_Backups")
		if _, err := os.Stat(backupDir); os.IsNotExist(err) {
			if err := os.MkdirAll(backupDir, 0755); err != nil {
				fmt.Printf("创建备份目录错误: %v\n", err)
				os.Exit(1)
			}
		}
		if err := createBackupFile(backupDir); err != nil {
			fmt.Println(err)
			os.Exit(1)
		}
	case "2":
		// macOS 模式
		fmt.Println("macOS 修改 ID 模式")
		homeDir := os.Getenv("HOME")
		if homeDir == "" {
			fmt.Println("无法获取用户主目录路径！")
			os.Exit(1)
		}
		filePath = filepath.Join(homeDir, "Library", "Application Support", "Cursor", "User", "globalStorage", "storage.json")
	case "3":
		// Linux 模式
		fmt.Println("Linux 修改 ID 模式")
		homeDir := os.Getenv("HOME")
		if homeDir == "" {
			fmt.Println("无法获取用户主目录路径！")
			os.Exit(1)
		}
		filePath = filepath.Join(homeDir, ".config", "Cursor", "User", "globalStorage", "storage.json")
	default:
		fmt.Println("输入无效，操作已取消。")
		os.Exit(1)
	}

	// 检查文件是否存在
	if _, err := os.Stat(filePath); os.IsNotExist(err) {
		fmt.Printf("文件 %s 不存在！\n", filePath)
		os.Exit(1)
	}

	// 执行修改操作
	if err := modifyDeviceIDs(filePath); err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
} 